package com.xhj.mybatis.scripting.xmltags;

import com.xhj.mybatis.executor.parameter.ParameterHandler;
import com.xhj.mybatis.mapping.BoundSql;
import com.xhj.mybatis.mapping.MappedStatement;
import com.xhj.mybatis.mapping.SqlSource;
import com.xhj.mybatis.scripting.LanguageDriver;
import com.xhj.mybatis.scripting.defaults.DefaultParameterHandler;
import com.xhj.mybatis.scripting.defaults.RawSqlSource;
import com.xhj.mybatis.session.Configuration;
import org.dom4j.Element;

/**
 * XMLLanguageDriver
 *
 * @author XJks
 * @description XMLLanguageDriver 是 MyBatis 用于解析 XML 脚本语言的驱动实现类。它实现了 LanguageDriver 接口，负责将 XML 或字符串脚本转换为可执行的 SQL 源对象。
 */
public class XMLLanguageDriver implements LanguageDriver {
    /**
     * 创建一个 ParameterHandler（参数处理器），用于将实际参数传递给 JDBC 语句。
     *
     * @param mappedStatement 当前正在执行的映射语句对象，包含 SQL 和相关配置信息
     * @param parameterObject 输入参数对象，可以为 null，表示 SQL 语句需要的参数
     * @param boundSql        动态 SQL 解析执行后的最终 SQL 及参数信息
     * @return 返回参数处理器对象，用于设置 SQL 参数
     * @see DefaultParameterHandler 默认参数处理器实现
     */
    @Override
    public ParameterHandler createParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
        // 使用默认参数处理器，将参数对象和 SQL 语句绑定
        return new DefaultParameterHandler(mappedStatement, parameterObject, boundSql);
    }

    /**
     * 创建一个 SqlSource（SQL 源），用于保存从 mapper XML 文件读取的 SQL 语句。
     * 该方法在启动时调用，用于解析类或 XML 文件中的映射语句。
     *
     * @param configuration MyBatis 全局配置对象
     * @param script        从 XML 文件解析出来的 dom4j 的 Element 节点，即 <select>、<insert>、<update>、<delete> 等节点
     * @param parameterType 从 mapper 方法或 XML 属性 parameterType 获取的参数类型，可以为 null
     * @return 返回 SQL 源对象，封装 SQL 语句和参数信息
     */
    @Override
    public SqlSource createSqlSource(Configuration configuration, Element script, Class<?> parameterType) {
        // 创建 XMLScriptBuilder 用于解析 XML 节点
        XMLScriptBuilder builder = new XMLScriptBuilder(configuration, script, parameterType);
        // 解析 XML 节点，生成 SqlSource
        return builder.parseScriptNode();
    }

    /**
     * 创建一个 SqlSource（SQL 源），用于保存从注解读取的 SQL 语句。
     * 该方法在启动时调用，用于解析类或 XML 文件中的映射语句。
     *
     * @param configuration MyBatis 全局配置对象
     * @param script        注解中的 SQL 内容（字符串形式）
     * @param parameterType 从 mapper 方法或 XML 属性 parameterType 获取的参数类型，可以为 null
     * @return 返回 SQL 源对象，封装 SQL 语句和参数信息
     */
    @Override
    public SqlSource createSqlSource(Configuration configuration, String script, Class<?> parameterType) {
        // todo:目前只支持解析静态 SQL，暂未实现动态 SQL 解析，所以直接返回 RawSqlSource。
        return new RawSqlSource(configuration, script, parameterType);
    }

}
